/* $Id: ControllerUnitTest.java 63 2010-02-14 13:52:34Z aaron.day $ */
package org.crazydays.gameplan.controller;


import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;

import org.junit.*;
import static org.junit.Assert.*;

import static org.easymock.EasyMock.*;
import static org.easymock.classextension.EasyMock.*;

import org.crazydays.gameplan.controller.Controller;
import org.crazydays.gameplan.map.GameMap;
import org.crazydays.gameplan.map.swing.CreateMapDialogFactory;
import org.crazydays.gameplan.map.swing.JCreateMapDialog;
import org.crazydays.gameplan.map.swing.JMapFrame;
import org.crazydays.gameplan.map.swing.JMapPropertiesDialog;
import org.crazydays.gameplan.map.swing.MapPropertiesDialogFactory;
import org.crazydays.gameplan.model.Model;
import org.crazydays.gameplan.view.View;

/**
 * ControllerUnitTest
 */
public class ControllerUnitTest
{
    /**
     * Test createDatabase().
     */
    @Test
    public void testCreateDatabase()
    {
        // mocks
        Model model = createMock(Model.class);

        // expect
        model.createDatabase();

        // replay
        replay(model);

        // setup
        Controller controller = new Controller();
        controller.setModel(model);

        // test
        controller.createDatabase();

        // verify
        verify(model);
    }

    /**
     * Test closeDatabase().
     */
    @Test
    public void testCloseDatabase()
    {
        // mocks
        Model model = createMock(Model.class);

        // expect
        model.closeDatabase();

        // replay
        replay(model);

        // setup
        Controller controller = new Controller();
        controller.model = model;

        // test
        controller.closeDatabase();

        // verify
        verify(model);
    }

    /**
     * Test addGameMap(IGameMap).
     */
    @Test
    public void testAddGameMap()
    {
        // mocks
        Model model = createMock(Model.class);
        GameMap gameMap = createMock(GameMap.class);

        // expect
        model.addGameMap(gameMap);

        // replay
        replay(model, gameMap);

        // setup
        Controller controller = new Controller();
        controller.model = model;

        // test
        controller.addGameMap(gameMap);

        // verify
        verify(model, gameMap);
    }

    /**
     * Test openGameMap(String).
     */
    @Test
    public void testOpenGameMap()
    {
        // objects
        String name = "name";

        // mocks
        Model model = createMock(Model.class);
        GameMap gameMap = createMock(GameMap.class);
        View view = createMock(View.class);

        // expect
        expect(model.getGameMap(name)).andReturn(gameMap);
        view.open(gameMap);

        // replay
        replay(model, gameMap, view);

        // setup
        Controller controller = new Controller();
        controller.model = model;
        controller.view = view;

        // test
        controller.openGameMap(name);

        // verify
        verify(model, gameMap, view);
    }

    /**
     * Test save(boolean).
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     */
    @Test
    public void testSave_saveas_badprompt()
        throws SecurityException, NoSuchMethodException
    {
        // mock
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForSaveFile") });
        Model model = createMock(Model.class);

        // expect
        expect(controller.promptForSaveFile()).andReturn(false);

        // replay
        replay(controller, model);

        // test
        controller.save(true);

        // verify
        verify(controller, model);
    }

    /**
     * Test save(boolean).
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IOException
     */
    @Test
    public void testSave_saveas()
        throws SecurityException, NoSuchMethodException, IOException
    {
        // mock
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForSaveFile") });
        Model model = createMock(Model.class);

        // expect
        expect(controller.promptForSaveFile()).andReturn(true);
        model.save();

        // setup
        controller.model = model;

        // replay
        replay(controller, model);

        // test
        controller.save(true);

        // verify
        verify(controller, model);
    }

    /**
     * Test save(boolean).
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IOException
     */
    @Test
    public void testSave_save()
        throws SecurityException, NoSuchMethodException, IOException
    {
        // mock
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForSaveFile") });
        Model model = createMock(Model.class);

        // expect
        expect(model.isSaveFileSet()).andReturn(false);
        expect(controller.promptForSaveFile()).andReturn(true);
        model.save();

        // setup
        controller.model = model;

        // replay
        replay(controller, model);

        // test
        controller.save(false);

        // verify
        verify(controller, model);
    }

    /**
     * Test openDatabase().
     * 
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws IOException
     */
    @Test
    public void testOpenDatabase()
        throws SecurityException, NoSuchMethodException, IOException
    {
        // objects
        File file = new File(".");

        // mocks
        Controller controller =
            createMock(Controller.class, new Method[] { Controller.class
                .getDeclaredMethod("promptForOpenFile") });
        Model model = createMock(Model.class);

        // expect
        expect(controller.promptForOpenFile()).andReturn(file);
        model.openDatabase(file);

        // replay
        replay(controller, model);

        // setup
        controller.model = model;

        // test
        controller.openDatabase();

        // verify
        verify(controller, model);
    }

    /**
     * Test toggleGrid().
     */
    @Test
    public void testToggleGrid()
    {
        // mocks
        Model model = createMock(Model.class);
        View view = createMock(View.class);

        // setup
        Controller controller = new Controller();
        controller.model = model;
        controller.view = view;

        // expect
        expect(view.toggleGrid()).andReturn(true);

        // replay
        replay(model, view);

        // test
        boolean result = controller.toggleGrid();

        // verify
        verify(model, view);

        assertEquals("result", true, result);
    }

    /**
     * Test openMapPropertiesDialog().
     */
    @Test
    public void testOpenMapPropertiesDialog()
    {
        // mocks
        View view = createMock(View.class);
        JMapFrame mapFrame = createMock(JMapFrame.class);
        MapPropertiesDialogFactory factory =
            createMock(MapPropertiesDialogFactory.class);
        GameMap gameMap = createMock(GameMap.class);
        JMapPropertiesDialog dialog = createMock(JMapPropertiesDialog.class);

        // setup
        Controller controller = new Controller();
        controller.setView(view);
        controller.setMapPropertiesDialogFactory(factory);

        // expect
        expect(view.getActiveMapFrame()).andReturn(mapFrame);
        expect(mapFrame.getGameMap()).andReturn(gameMap);
        expect(factory.buildMapPropertiesDialog(gameMap)).andReturn(dialog);
        dialog.setVisible(true);

        // replay
        replay(view, mapFrame, factory, gameMap, dialog);

        // test
        controller.openMapPropertiesDialog();

        // verify
        verify(view, mapFrame, factory, gameMap, dialog);
    }

    /**
     * Test openCreateMapDialog().
     */
    @Test
    public void testOpenCreateMapDialog()
    {
        // mocks
        CreateMapDialogFactory factory =
            createMock(CreateMapDialogFactory.class);
        JCreateMapDialog dialog = createMock(JCreateMapDialog.class);

        // setup
        Controller controller = new Controller();
        controller.setCreateMapDialogFactory(factory);

        // expect
        expect(factory.getCreateMapDialog()).andReturn(dialog);
        dialog.setVisible(true);

        // replay
        replay(factory, dialog);

        // test
        controller.openCreateMapDialog();

        // verify
        verify(factory, dialog);
    }

    /**
     * Test openMapPropertiesDialog().
     */
    @Test
    public void testOpenMapPropertiesDialog_nomapframe()
    {
        // mocks
        View view = createMock(View.class);

        // setup
        Controller controller = new Controller();
        controller.setView(view);

        // expect
        expect(view.getActiveMapFrame()).andReturn(null);

        // replay
        replay(view);

        // test
        controller.openMapPropertiesDialog();

        // verify
        verify(view);
    }
}
